package com.richard.room.app;

import com.richard.library.basic.basic.BasicBindingActivity;
import com.richard.library.basic.util.LogUtil;
import com.richard.library.http.converter.JsonConverter;
import com.richard.library.simplerx.XObservable;
import com.richard.library.simplerx.XObservableOnSubscribe;
import com.richard.library.simplerx.XSubscribe;
import com.richard.room.app.databinding.ActivityMainBinding;
import com.richard.room.app.entity.Book;
import com.richard.room.app.entity.User;
import com.richard.room.app.entity.User_;
import com.richard.room.operator.api.RoomOperator;

import java.util.ArrayList;
import java.util.Date;
import java.util.List;

import io.reactivex.rxjava3.disposables.Disposable;

/**
 * @author: Richard
 * @createDate: 2023/8/7 11:51
 * @version: 1.0
 * @description: 描述
 */
public class MainActivity extends BasicBindingActivity<ActivityMainBinding> {

    @Override
    public void initLayoutView() {
        setContentView(R.layout.activity_main);
    }

    @Override
    public void initData() {
    }

    @Override
    public void bindListener() {
        binding.bvTestInsert.setOnClickListener((v) -> {
            //this.testInsert();
            RoomOperator.op(User.class).updateBuilder()
                    .set(User_.name, "李四222")
                    .build()
                    .equal(User_.id, 2)
                    .update();
        });

        binding.bvTestSave.setOnClickListener((v) -> {
            this.testSave();
        });

        binding.bvTestDelete.setOnClickListener((v) -> {
            RoomOperator.op(User.class).deleteAll();
            RoomOperator.op(Book.class).deleteAll();
        });

        binding.bvTestDeleteBatch.setOnClickListener((v) -> {
            this.testDeleteByIds(binding.etUserId.getText().toString().trim().split(","));
        });

        binding.bvTestQuery.setOnClickListener((v) -> {
            List<User> users = RoomOperator.op(User.class)
                    .query(User_.name,User_.age.avg(2))
                    .build()
                    .page(1, 1)
                    .find();
            LogUtil.dTag("testtt", LogUtil.formatJson(JsonConverter.toJson(users)));

//            this.testQuery();

//            List<Book> result = RoomOperator
//                    .op(User.class)
//                    .query()
//                    .equal(User_.name,1).reverse()
//                    .equal(RoomOperator.op(Book.class).query(Book_.uid).buildChildQuery().page(1,1),User_.age)
//                    .equal(RoomOperator.op(Book.class).query(Book_.uid).buildChildQuery().page(1,1),1)
//                    .equal(User_.name,RoomOperator.op(Book.class).query(Book_.uid).buildChildQuery().page(1,1))
//                    .equal(RoomOperator.op(Book.class).query(Book_.uid).buildChildQuery().page(1,1),RoomOperator.op(Book.class).query(Book_.uid).buildChildQuery().page(1,1)).not()
//                    .and(new PropertyCondition(new Expression(
//                            RoomOperator.op(User.class)
//                                    .query(User_.id)
//                                    .buildChildQuery()
//                                    .page(1,1)
//                                    .getSql()
//                            , ExpressionType.notNull
//                    )))
//                    .build()
//                    .orderBy(new Property[]{User_.age,User_.id},new OrderByType[]{OrderByType.asc,OrderByType.desc})
//                    .page(20,1)
//                    .find(Book.class);

//            LogUtil.dTag("testtt",LogUtil.formatJson(JsonConverter.toJson(result)));
        });

        binding.bvTestGenerate.setOnClickListener((v) -> {
            this.testGenerate();
        });
    }

    private void testGenerate() {
        XObservable
                .create(new XObservableOnSubscribe<Boolean>() {
                    @Override
                    public Boolean run() throws Throwable {
                        String[] randUser = new String[]{"刘德华", "张三", "Richard", "Jerry", "李四", "成龙", "周星驰", "关晓彤", "肖战", "赵璐思"};
                        List<User> userList = new ArrayList<>();
                        for (int j = 0; j < 100; j++) {
                            User user = new User();
                            user.setName(randUser[(int) (Math.random() * 10)]);
                            user.setAge((int) (Math.random() * 100));
                            userList.add(user);
                        }

                        long startTime = System.currentTimeMillis();
                        JsonConverter.toJSONArray(userList);
                        LogUtil.dTag("testtt", String.format("=======生成耗时%s ms=======>", System.currentTimeMillis() - startTime));
                        return true;
                    }
                })
                .bindLife(this)
                .toAsyncSubscribe(new XSubscribe<Boolean>() {

                    @Override
                    public void onXSubscribe(Disposable d) {
                        getUIView().showLoading();
                    }

                    @Override
                    public void onXNext(Boolean data) {
                        getUIView().dismissLoading("完成", true);
                    }

                    @Override
                    public void onXError(Throwable e) {
                        getUIView().dismissLoading();
                        getUIView().showErrorMsg(e.getMessage());
                    }
                });
    }

    private void testDeleteByIds(final String[] ids) {
        XObservable
                .create(new XObservableOnSubscribe<Boolean>() {
                    @Override
                    public Boolean run() throws Throwable {
                        long startTime = System.currentTimeMillis();
//                        DB.get().testDao().de(userList);
                        RoomOperator.op(User.class).deleteByIds(ids);
                        LogUtil.dTag("testtt", String.format("=======指定删除user耗时%s ms=======>", System.currentTimeMillis() - startTime));
                        return true;
                    }
                })
                .bindLife(this)
                .toAsyncSubscribe(new XSubscribe<Boolean>() {

                    @Override
                    public void onXSubscribe(Disposable d) {
                        getUIView().showLoading();
                    }

                    @Override
                    public void onXNext(Boolean data) {
                        getUIView().dismissLoading("删除完成");
                    }

                    @Override
                    public void onXError(Throwable e) {
                        getUIView().dismissLoading();
                        getUIView().showErrorMsg(e.getMessage());
                    }
                });
    }

    private void testSave() {
        XObservable
                .create(new XObservableOnSubscribe<Boolean>() {
                    @Override
                    public Boolean run() throws Throwable {
                        String[] randUser = new String[]{"刘德华", "张三", "Richard", "Jerry", "李四", "成龙", "周星驰", "关晓彤", "肖战", "赵璐思"};
                        List<User> userList = new ArrayList<>();
                        for (int j = 0; j < 100000; j++) {
                            User user = new User();
                            user.setName(randUser[(int) (Math.random() * 10)]);
                            user.setAge((int) (Math.random() * 100));
                            userList.add(user);
                        }

                        long startTime = System.currentTimeMillis();
//                        List<Long> uidList = DB.get().testDao().save(userList);
                        List<Long> uidList = RoomOperator.op(User.class).saveAndReturnIds(userList);
                        LogUtil.dTag("testtt", String.format("=======保存User[%s条]耗时%s ms=======>", uidList.size(), System.currentTimeMillis() - startTime));

                        String[] randName = new String[]{"安徒生童话", "三国演义", "封神榜", "语文", "化学", "生物", "地理", "音乐", "西游记", "绘画"};
                        List<Book> bookList = new ArrayList<>();
                        for (long uid : uidList) {
                            int bookCount = (int) (Math.random() * 5) + 1;
                            for (int i = 0; i < bookCount; i++) {
                                Book book = new Book();
                                book.setName(randName[(int) (Math.random() * 10)]);
                                book.setPage((int) (Math.random() * 1000));
                                book.setUid(uid);
                                bookList.add(book);
                            }
                        }

                        startTime = System.currentTimeMillis();
//                        DB.get().testDao().saveBook(bookList);
                        RoomOperator.op(Book.class).save(bookList);
                        LogUtil.dTag("testtt", String.format("=======保存Book[%s条]耗时%s ms=======>", bookList.size(), System.currentTimeMillis() - startTime));


                        return true;
                    }
                })
                .bindLife(this)
                .toAsyncSubscribe(new XSubscribe<Boolean>() {

                    @Override
                    public void onXSubscribe(Disposable d) {
                        getUIView().showLoading();
                    }

                    @Override
                    public void onXNext(Boolean data) {
                        getUIView().dismissLoading("添加完成", true);
                    }

                    @Override
                    public void onXError(Throwable e) {
                        getUIView().dismissLoading(e.getMessage(), false);
                    }
                });
    }

    private void testInsert() {
        XObservable
                .create(new XObservableOnSubscribe<Boolean>() {
                    @Override
                    public Boolean run() throws Throwable {
                        String[] randUser = new String[]{"刘德华", "张三", "Richard", "Jerry", "李四", "成龙", "周星驰", "关晓彤", "肖战", "赵璐思"};
                        List<User> userList = new ArrayList<>();
                        for (int j = 0; j < 1; j++) {
                            User user = new User();
                            user.setBirthday(new Date());
                            user.setName(randUser[(int) (Math.random() * 10)]);
                            user.setAge((int) (Math.random() * 100));
                            user.setUpdate_time(System.currentTimeMillis());

                            UserDTO userDTO = new UserDTO();
                            userDTO.setName("哈哈");
                            userDTO.setJob("IT");
                            userDTO.setFen(10);
                            user.setUserDTO(List.of(userDTO));

                            userList.add(user);
                        }

                        long startTime = System.currentTimeMillis();
//                        List<Long> uidList = DB.get().testDao().insert(userList);
                        List<Long> uidList = RoomOperator.op(User.class).insertAndReturnIds(userList);
                        LogUtil.dTag("testtt", String.format("=======添加User[%s条]耗时%s ms=======>", uidList.size(), System.currentTimeMillis() - startTime));

                        String[] randName = new String[]{"安徒生童话", "三国演义", "封神榜", "语文", "化学", "生物", "地理", "音乐", "西游记", "绘画"};
                        List<Book> bookList = new ArrayList<>();
                        for (long uid : uidList) {
                            int bookCount = (int) (Math.random() * 5) + 1;
                            for (int i = 0; i < bookCount; i++) {
                                Book book = new Book();
                                book.setName(randName[(int) (Math.random() * 10)]);
                                book.setPage((int) (Math.random() * 1000));
                                book.setUid(uid);
                                bookList.add(book);
                            }
                        }

                        startTime = System.currentTimeMillis();
//                        DB.get().testDao().insertBook(bookList);
                        RoomOperator.op(Book.class).insert(bookList);
                        LogUtil.dTag("testtt", String.format("=======添加Book[%s条]耗时%s ms=======>", bookList.size(), System.currentTimeMillis() - startTime));

                        return true;
                    }
                })
                .bindLife(this)
                .toAsyncSubscribe(new XSubscribe<Boolean>() {

                    @Override
                    public void onXSubscribe(Disposable d) {
                        getUIView().showLoading();
                    }

                    @Override
                    public void onXNext(Boolean data) {
                        getUIView().dismissLoading("添加完成", true);
                    }

                    @Override
                    public void onXError(Throwable e) {
                        getUIView().dismissLoading(e.getMessage(), false);
                    }
                });
    }

    private void testQuery() {
        XObservable
                .create(new XObservableOnSubscribe<List<User>>() {
                    @Override
                    public List<User> run() throws Throwable {
                        LogUtil.dTag("testtt", "User条数:" + RoomOperator.op(User.class).count());
                        LogUtil.dTag("testtt", "Book条数:" + RoomOperator.op(Book.class).count());

                        long startTime = System.currentTimeMillis();
//                        List<User> data = RoomOperator
//                                .op(User.class)
//                                .innerJoin(Book_._instance)
//                                .equal(User_.id,Book_.uid)
//                                .query()
//                                .contains(User_.name,"chard")
//                                .build()
//                                .page(100,1)
//                                .orderBy(User_.age,OrderByType.desc)
//                                .find();

                        List<User> data = RoomOperator.op(User.class)
                                .findPage(10, 1);


                        LogUtil.dTag("testtt", String.format("=======查询耗时%s ms=======>", System.currentTimeMillis() - startTime));

                        return data;
                    }
                })
                .bindLife(this)
                .toAsyncSubscribe(new XSubscribe<List<User>>() {

                    @Override
                    public void onXSubscribe(Disposable d) {
                        getUIView().showLoading();
                    }

                    @Override
                    public void onXNext(List<User> data) {
                        getUIView().dismissLoading();
                        getUIView().showMsgDialog(JsonConverter.toJson(data), null);
                    }

                    @Override
                    public void onXError(Throwable e) {
                        getUIView().dismissLoading();
                        getUIView().showErrorMsg(e.getMessage());
                    }
                });
    }
}
